﻿using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Yitter.IdGenerator;
using FytSoa.DynamicApi;
using FytSoa.Quartz.Extensions;
using Digitalmes.Application;
using Digitalmes.Common.Cache;
using Digitalmes.Generator;
using Digitalmes.Sugar;

namespace Digitalmes.CrossCutting;

public static class BootStrapperIoC
{
    /// <summary>
    /// 注册应用基本服务
    /// </summary>
    /// <param name="builder"></param>
    public static void RegisterAppServices(this IHostBuilder builder)
    {
        builder.ConfigureServices((hostBuilder, services) =>
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            // application services
            var assembly = typeof(IDynamicWebApiService).Assembly;
            services.RegisterScoped<IDynamicWebApiService>(assembly);
            services.RegisterScoped<IApplicationService>(assembly);
            services.AddApplication(hostBuilder.Configuration);

            services.AddMemoryCache();

            services.AddScoped<ICacheService, MemoryService>();

            // code generator
            services.AddScoped<IGeneratorService, GeneratorService>();

            services.AddSqlSugarSetup(hostBuilder);

            // Quartz
            services.AddQuartz();
            //services.AddQuartzClassJobs();

            // dynamic webapi
            services.AddDynamicWebApi();
        });

        // 雪花Id
        YitIdHelper.SetIdGenerator(new IdGeneratorOptions
        {
            WorkerId = 1, // 机器码 全局唯一
            WorkerIdBitLength = 1, // 机器码位长 默认值6，取值范围 [1, 19]
            SeqBitLength = 6, // 序列数位长 默认值6，取值范围 [3, 21]（建议不小于4，值越大性能越高、Id位数也更长）
        });

        // Jwt Config
        builder.AddJwtConfiguration();
    }

    private static void RegisterScoped<T>(this IServiceCollection services, Assembly assembly)
        where T : class
    {
        var serviceTypes = assembly.GetTypes().Where(u => u.IsClass && !u.IsAbstract && !u.IsGenericType && !u.IsInterface
                    && typeof(T).IsAssignableFrom(u));
        foreach (var item in serviceTypes)
        {
            services.AddScoped(item);
        }
    }
}
